package com.gaojinqi.sys.modular.rbac.controller;

import com.gaojinqi.base.common.exception.BizRuntimeException;
import com.gaojinqi.base.common.model.PageReq;
import com.gaojinqi.base.common.validation.group.Insert;
import com.gaojinqi.base.common.validation.group.Update;
import com.gaojinqi.base.common.vo.IResult;
import com.gaojinqi.base.common.vo.PageResultVo;
import com.gaojinqi.base.common.vo.ResultVo;
import com.gaojinqi.sys.common.enums.GenderEnum;
import com.gaojinqi.sys.modular.rbac.model.Role;
import com.gaojinqi.sys.modular.rbac.model.User;
import com.gaojinqi.sys.modular.rbac.service.RoleService;
import com.gaojinqi.sys.modular.rbac.service.UserService;
import com.gaojinqi.sys.modular.rbac.vo.RoleSaveVo;
import com.gaojinqi.sys.modular.rbac.vo.RoleSearchVo;
import com.gaojinqi.sys.modular.rbac.vo.UserSaveVo;
import com.gaojinqi.sys.modular.rbac.vo.UserSearchVo;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.properties.IntegerProperty;
import io.swagger.models.properties.StringProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.Collection;
import java.util.Objects;

/**
 * 用户 - 控制层
 *
 * @author gaojinqi
 * @version 1.0
 * @since 2020年05月26日
 */
@Api(tags = "用户")
@RestController
@Validated
@Slf4j
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private RoleService roleService;
    @Autowired
    private UserService userService;

    @ApiOperation(value = "新增用户")
    @PostMapping
    public IResult<User> addUser(@Validated(Insert.class) @RequestBody UserSaveVo param) {
        User user = userService.findByUserName(param.getUserName());
        if (user != null) {
            throw new BizRuntimeException("该用户名已存在");
        }
        User entity = new User();
        BeanUtils.copyProperties(param, entity);
        if (entity.getGender() == null) {
            entity.setGender(GenderEnum.UNKNOW.getCode());
        }
        userService.save(entity);
        return ResultVo.suc(entity);
    }

    @ApiOperation(value = "修改用户")
    @PutMapping(value = "/{userId}")
    public IResult<User> updateUser(
            @NotBlank(message = "请输入用户ID") @PathVariable(value = "userId") String userId,
            @Validated(Update.class) @RequestBody UserSaveVo param) {
        User user = userService.findByUserName(param.getUserName());
        if (user != null && !Objects.equals(user.getUserId(), userId)) {
            throw new BizRuntimeException("该用户名已存在");
        }
        User entity = new User();
        entity.setUserId(userId);
        BeanUtils.copyProperties(param, entity);
        userService.update(entity);
        return ResultVo.suc(entity);
    }

    @ApiOperation(value = "删除用户")
    @DeleteMapping(value = "/{userIds}")
    @ApiImplicitParam(name = "userIds", value = "用户ID list", allowMultiple = true, paramType = "path", dataType = StringProperty.TYPE, required = true)
    public IResult<String> deleUser(
            @NotEmpty(message = "请输入用户ID") @PathVariable(value = "userIds") String[] userIds) {
        userService.deleteByIds(Lists.newArrayList(userIds));
        return ResultVo.suc("删除成功");
    }

    @ApiOperation(value = "根据ID查询用户详情")
    @GetMapping(value = "/{userId}")
    public IResult<User> getUser(
            @NotBlank(message = "请输入用户ID") @PathVariable(value = "userId") String userId) {
        return ResultVo.suc(userService.findById(userId));
    }

    @ApiOperation(value = "分页查询用户")
    @GetMapping
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码", defaultValue = "1", dataType = IntegerProperty.TYPE, paramType = "query"),
            @ApiImplicitParam(name = "size", value = "每页条目数量", dataType = IntegerProperty.TYPE, defaultValue = "10", paramType = "query"),
            @ApiImplicitParam(name = "sortMode", value = "排序方式，倒序为0，正序为1", dataType = IntegerProperty.TYPE, defaultValue = "0", paramType = "query"),
    })
    public IResult<Collection<User>> page(UserSearchVo param, PageReq pageReq) {
        User entity = new User();
        BeanUtils.copyProperties(param, entity);
        return PageResultVo.suc(userService.page(entity, pageReq));
    }

    @ApiOperation(value = "查询指定用户已分配的角色")
    @GetMapping("/{userId}/role")
    public IResult<Collection<Role>> findAssignedRolesByUserId(
            @NotBlank(message = "请选择用户") @PathVariable(value = "userId") String userId) {
        return ResultVo.suc(roleService.findRolesByUserId(userId));
    }

    @ApiOperation(value = "给指定用户分配角色")
    @PutMapping("/{userId}/role")
    @ApiImplicitParam(name = "roleIds", value = "角色ID集合", dataType = StringProperty.TYPE, allowMultiple = true, paramType = "query")
    public IResult<Object> assignRolesToUserId(
            @NotBlank(message = "请选择角色") @PathVariable(value = "userId") String userId,
            @NotEmpty(message = "请选择要分配的权限") String[] roleIds) {
        roleService.assignRolesToUserId(userId, Sets.newHashSet(roleIds));
        return ResultVo.suc("分配角色成功");
    }

}
